// 移动构造踩坑点
// 移动构造函数在 初始化列表中通过 std::move 对成员变量初始化之后，
// 该构造函数参数可能变为无效的，依赖于被初始化的成员变量的构造函数的实现。

#include <iostream>
#include <string>

class Foo {
 public:
  Foo(const std::string& name) : mName(name) {
    std::cout << "Foo(const std::string& name), name:" << name << std::endl;
  }

  Foo(std::string&& name) : mName(std::move(name)) {
    // 此处注意坑点：
    // 移动构造中，在初始化时，通过 std::move 将 name 传递给 string
    // 的构造函数，发生了权限转移，到这里，name 变成了空.
    std::cout << "Foo(std::string&& name), name:" << name
              << ",mName:" << GetName() << std::endl;
  }

  std::string GetName() const { return mName; }

  virtual ~Foo() { std::cout << "~Foo()" << std::endl; }

 private:
  std::string mName;
};

class Bar : public Foo {
 public:
  Bar(const std::string& name) : Foo(name) {
    std::cout << "Bar(const std::string& name)， name:" << name << std::endl;
  }

  Bar(std::string&& name) : Foo(std::move(name)) {
    // 此处注意坑点：
    // 父类的移动构造中使 name发生了权限转移，到这里， name 变成了空.
    std::cout << "Bar(std::string&& name), name:" << name
              << ",mName:" << GetName() << std::endl;
  }

  virtual ~Bar() { std::cout << "Bar::~Bar()" << std::endl; }
};

int main() {
  Bar bar("NickName");

  return 0;
}